package com.ngkj.zmfptwebsocket.handler;

import com.google.gson.Gson;
import com.ngkj.zmfptCommon.common.bean.ChatMessage;
import com.ngkj.zmfptwebsocket.chatModule.service.write.ChatMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author ChenHN
 * @since 2021/11/17 creation
 **/
@Slf4j
@Component
@ServerEndpoint("/websocket/{userId}")
public class WsServerEndpoint {

    private static ConcurrentHashMap<String, Session> map = new ConcurrentHashMap<>();
    private static Gson gson = new Gson();
    private static AtomicInteger onlineNum = new AtomicInteger(0);
    private static RedisTemplate redisTemplate;
    private String userId;
    private Session session;
    public static ConcurrentHashMap<String, Session> getMap() {
        return map;
    }
    private static ChatMessageService chatMessageService;

    @Autowired
    public void setChatMessageService(ChatMessageService chatMessageService){
        this.chatMessageService = chatMessageService;
    }

    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        log.info("用户：{}与建立ws连接", userId);
        this.session = session;
        this.userId = userId;
        if (map.containsKey(userId)) {
            map.remove(userId);
            map.put(userId, session);
        } else {
            map.put(userId, session);
            onlineNum.getAndIncrement();
        }
        log.info("当前在线人数为：{}", onlineNum.get());
    }

    @OnMessage
    public void onMessage(@RequestBody String data) throws IOException {
        ChatMessage message = gson.fromJson(data, ChatMessage.class);

        if (message.getToUserId().isEmpty()) {
            //广播
        } else {
            //显示已读
            if ("09".equals(message.getMessageType())){
                chatMessageService.updateIsRead(message);
                return ;
            }
            String toUserId = message.getToUserId();
            Session toSession = map.get(toUserId);
            message.setUserId(this.userId);
            message.setIsRead("02");
            message.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
            String content = gson.toJson(message);
            //对方用户在线
            if (!ObjectUtils.isEmpty(toSession)) {
                sendToOne(content, toSession);
            }else if ("03".equals( message.getMessageType())){
                Map<String,Object> map = new HashMap<>();
                map.put("messageType","404");
                String content1 = gson.toJson(map);
                sendToOne(content1,session);
            }
            if ("03".equals( message.getMessageType())){
                message.setContent("视频通话");
            }
            if ("04".equals( message.getMessageType())||"05".equals( message.getMessageType()) || "07".equals(message.getMessageType()) ){
                return ;
            }
            String userId = message.getUserId();
            String cacheWsSave = null;
            String cacheWsShow = null;
            int chat1 = Integer.parseInt(userId);
            int chat2 = Integer.parseInt(toUserId);
            if (chat1<chat2) {
                message.setConnection(userId + "-" + toUserId);
                cacheWsSave = "websocket_save " + userId + "-" + toUserId;
                cacheWsShow = "websocket_show " + userId + "-" + toUserId;
            }else{
                message.setConnection(toUserId + "-" + userId);
                cacheWsSave = "websocket_save " + toUserId + "-" + userId;
                cacheWsShow = "websocket_show " + toUserId + "-" + userId;
            }
            redisTemplate.opsForList().rightPush(cacheWsSave, message);
            redisTemplate.opsForList().rightPush(cacheWsShow, message);
        }
    }

    @OnClose
    public void onClose() throws IOException {
        if (map.containsKey(this.userId)) {
            map.remove(this.userId);
            onlineNum.getAndDecrement();
        }
        if (!ObjectUtils.isEmpty(this.session)) {
            this.session.close();
        }
        log.info("用户：{} 已下线！", this.userId);
    }

    @OnError
    public void onError(Throwable error) {
        System.out.println("用户错误:" + this.userId + ",原因:" + error.getMessage());
        error.printStackTrace();
    }

    public void sendToOne(String text, Session toSession) throws IOException {
        synchronized(this.session) {
            toSession.getBasicRemote().sendText(text);
        }
    }
}
